import { Router, Request, Response, NextFunction, RequestHandler } from 'express';
import { ValidationChain } from 'express-validator';
import { AuthenticatedRequest, AuthUser } from './auth';
import { User } from './prisma-types';

export interface TypedRequestHandler<T = any, U = AuthUser> {
  (req: Request & { user?: U; body?: T }, res: Response, next: NextFunction): Promise<void> | void;
}

export interface AuthenticatedHandler<T = any> {
  (req: AuthenticatedRequest<T>, res: Response, next: NextFunction): Promise<void> | void;
}

export interface RouteConfig {
  path: string;
  method: 'get' | 'post' | 'put' | 'delete' | 'patch';
  handler: AuthenticatedHandler;
  middleware?: Array<RequestHandler | ValidationChain>;
  validation?: ValidationChain[];
}

export type RouterType = Router;

export type AsyncHandler<T = any> = (
  req: AuthenticatedRequest<T>,
  res: Response,
  next: NextFunction
) => Promise<any>;

export interface RouteDefinition {
  path: string;
  method: string;
  middlewares: Array<RequestHandler | ValidationChain>;
  handler: AsyncHandler;
}

export type MiddlewareFunction = RequestHandler | ValidationChain;

export const createTypedRouter = (): RouterType => Router();

// Helper for converting handlers with proper type inference
export function asRequestHandler<T = any>(
  handler: AuthenticatedHandler<T>
): RequestHandler {
  return (req, res, next) => {
    return handler(req as AuthenticatedRequest<T>, res, next);
  };
}

// Helper for converting middleware
export function asMiddleware(
  middleware: RequestHandler | ValidationChain
): RequestHandler {
  return middleware;
}

// Type guard for checking if request is authenticated
export function isAuthenticated(
  req: Request
): req is AuthenticatedRequest {
  return req.user !== undefined;
}

// Helper for chaining middleware with proper types
export function chainMiddleware(
  ...middleware: (RequestHandler | ValidationChain)[]
): RequestHandler[] {
  return middleware.map(m => asMiddleware(m));
}
